package com.xbongbong.paas.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.xbongbong.paas.constant.MessageConstant;
import com.xbongbong.paas.domain.entity.AttrTrashEntity;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.feign.WorkOrderV2ExplainFeignClient;
import com.xbongbong.paas.help.ProUpdateHelp;
import com.xbongbong.paas.model.AttrTrashModel;
import com.xbongbong.paas.pojo.dto.AttrTrashDeleteDTO;
import com.xbongbong.paas.pojo.vo.AttrTrashDeleteVO;
import com.xbongbong.paas.service.abstracts.AbstractPaasFormAttrTrashService;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.wrap.UserVO;
import com.xbongbong.paas.toolbox.wrap.XbbResponse;
import com.xbongbong.paas.util.ExplainUtil;
import com.xbongbong.pro.domain.entity.UpdateDataEntity;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.formdata.pojo.dto.FieldExistDataDTO;
import com.xbongbong.pro.formdata.pojo.vo.FieldExistDataVO;
import com.xbongbong.saas.domain.entity.AssembleProductEntity;
import com.xbongbong.saas.domain.entity.BomProductEntity;
import com.xbongbong.saas.domain.entity.ContractProductEntity;
import com.xbongbong.saas.domain.entity.InstockProductEntity;
import com.xbongbong.saas.domain.entity.InventoryProductEntity;
import com.xbongbong.saas.domain.entity.OpportunityProductEntity;
import com.xbongbong.saas.domain.entity.OutstockProductEntity;
import com.xbongbong.saas.domain.entity.ProductionOrderProductEntity;
import com.xbongbong.saas.domain.entity.PurchaseProductEntity;
import com.xbongbong.saas.domain.entity.QuotationProductEntity;
import com.xbongbong.saas.domain.entity.ReturnedPurchaseProductEntity;
import com.xbongbong.saas.domain.entity.SupplierProductEntity;
import com.xbongbong.saas.domain.entity.TransferProductEntity;
import com.xbongbong.saas.domain.entity.WorkOrderProductEntity;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.AssembleEnum;
import com.xbongbong.saas.enums.business.BomBillEnum;
import com.xbongbong.saas.enums.business.ContractEnum;
import com.xbongbong.saas.enums.business.InstockEnum;
import com.xbongbong.saas.enums.business.InventoryEnum;
import com.xbongbong.saas.enums.business.OutstockEnum;
import com.xbongbong.saas.enums.business.ProductionOrderEnum;
import com.xbongbong.saas.enums.business.PurchaseEnum;
import com.xbongbong.saas.enums.business.QuotationEnum;
import com.xbongbong.saas.enums.business.RefundEnum;
import com.xbongbong.saas.enums.business.ReturnedPurchaseEnum;
import com.xbongbong.saas.enums.business.SalesOpportunityEnum;
import com.xbongbong.saas.enums.business.SupplierEnum;
import com.xbongbong.saas.enums.business.TransferEnum;
import com.xbongbong.saas.enums.business.WorkOrderEnum;
import com.xbongbong.saas.model.AssembleProductModel;
import com.xbongbong.saas.model.BomProductModel;
import com.xbongbong.saas.model.ContractProductModel;
import com.xbongbong.saas.model.InstockProductModel;
import com.xbongbong.saas.model.InventoryProductModel;
import com.xbongbong.saas.model.OpportunityProductModel;
import com.xbongbong.saas.model.OutstockProductModel;
import com.xbongbong.saas.model.PaasFormSubDataModel;
import com.xbongbong.saas.model.ProductionOrderProductModel;
import com.xbongbong.saas.model.PurchaseProductModel;
import com.xbongbong.saas.model.QuotationProductModel;
import com.xbongbong.saas.model.ReturnedPurchaseProductModel;
import com.xbongbong.saas.model.SupplierProductModel;
import com.xbongbong.saas.model.TransferProductModel;
import com.xbongbong.saas.model.WorkOrderProductModel;
import org.apache.commons.collections4.CollectionUtils;
import org.elasticsearch.action.support.WriteRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;

/**
 *
 * @author 魏荣杰
 * @date 2021/3/5 13:52
 * @since
 * @version
 */
@Service("paasFormAttrTrashServiceImpl")
public class PaasFormAttrTrashServiceImpl extends AbstractPaasFormAttrTrashService {
    private static final Logger LOG = LoggerFactory.getLogger(PaasFormAttrTrashServiceImpl.class);


    @Resource
    private AttrTrashModel attrTrashModel;
    @Resource
    private ContractProductModel contractProductModel;
    @Resource
    private OpportunityProductModel opportunityProductModel;
    @Resource
    private QuotationProductModel quotationProductModel;
    @Resource
    private SupplierProductModel supplierProductModel;
    @Resource
    private PurchaseProductModel purchaseProductModel;
    @Resource
    private ReturnedPurchaseProductModel returnedPurchaseProductModel;
    @Resource
    private BomProductModel bomProductModel;
    @Resource
    private ProductionOrderProductModel productionOrderProductModel;
    @Resource
    private AssembleProductModel assembleProductModel;
    @Resource
    private InstockProductModel instockProductModel;
    @Resource
    private OutstockProductModel outstockProductModel;
    @Resource
    private InventoryProductModel inventoryProductModel;
    @Resource
    private TransferProductModel transferProductModel;
    @Resource
    private WorkOrderProductModel workOrderProductModel;
    @Resource
    private PaasFormSubDataModel paasFormSubDataModel;
    @Resource
    private ProUpdateHelp proUpdateHelp;
    @Resource
    private WorkOrderV2ExplainFeignClient workOrderV2ExplainFeignClient;

    @Override
    public FieldExistDataVO fieldExistData(FieldExistDataDTO fieldExistDataDTO) throws XbbException {
        if (XbbRefTypeEnum.workOrderV2Form().contains(fieldExistDataDTO.getBusinessType())) {
            XbbResponse<FieldExistDataVO> xbbResponse = workOrderV2ExplainFeignClient.fieldExistData(fieldExistDataDTO, LocaleContextHolder.getLocale().toString());
            if (!xbbResponse.isSuccess()) {
                throw new XbbException(xbbResponse.getCode(), xbbResponse.getMsg());
            }
            return xbbResponse.getResult();
        }
        return super.fieldExistData(fieldExistDataDTO);
    }

    @Override
    public boolean isProductSubKey(String attr, Integer businessType, String subAttr, String corpid, Long formId, Integer fieldType) {
        Integer isArray = 0;
        if (Objects.equals(FieldTypeEnum.COMBO_CHECK.getType(), fieldType)
                || Objects.equals(FieldTypeEnum.CHECKBOX_GROUP.getType(), fieldType)
                || Objects.equals(FieldTypeEnum.USER_GROUP.getType(), fieldType)
                || Objects.equals(FieldTypeEnum.DEPT_GROUP.getType(), fieldType)
                || Objects.equals(FieldTypeEnum.IMAGE.getType(), fieldType)
                || ExplainUtil.isSubForm(fieldType)
        ){
            isArray = 1;
        }
        boolean canDelete = true;
        XbbRefTypeEnum xbbRefTypeEnum = XbbRefTypeEnum.getByCode(businessType);
        switch (xbbRefTypeEnum){
            case CONTRACT:
                if (Objects.equals(subAttr,ContractEnum.PRODUCT.getAttr())) {
                    attr = "$." + attr;
                    Long id = contractProductModel.isProductSubAttrExist(attr, corpid, XbbRefTypeEnum.CONTRACT.getCode(), formId, isArray);
                    if (Objects.nonNull(id)) {
                        canDelete = false;
                    }
                }
                break;
            case SALES_OPPORTUNITY:
                if (Objects.equals(subAttr, SalesOpportunityEnum.PRODUCTS.getAttr())) {
                    attr = "$." + attr;
                    Long id = opportunityProductModel.isProductSubAttrExist(attr, corpid, formId, isArray);
                    if (Objects.nonNull(id)) {
                        canDelete = false;
                    }
                }
                break;
            case REFUND:
                if (Objects.equals(subAttr,RefundEnum.PRODUCTS.getAttr())) {
                    attr = "$." + attr;
                    Long id = contractProductModel.isProductSubAttrExist(attr,corpid,XbbRefTypeEnum.REFUND.getCode(), formId, isArray);
                    if (Objects.nonNull(id)) {
                        canDelete = false;
                    }
                }
                break;
            case QUOTATION:
                if (Objects.equals(subAttr, QuotationEnum.PRODUCT.getAttr())) {
                    attr = "$." + attr;
                    Long id = quotationProductModel.isProductSubAttrExist(attr, corpid, isArray);
                    if (Objects.nonNull(id)) {
                        canDelete = false;
                    }
                }
                break;
            case SUPPLIER:
                if (Objects.equals(subAttr, SupplierEnum.PRODUCT_LIST.getAttr())) {
                    attr = "$." + attr;
                    Long id = supplierProductModel.isProductSubAttrExist(attr, corpid, isArray);
                    if (Objects.nonNull(id)) {
                        canDelete = false;
                    }
                }
                break;
            case PURCHASE:
                if (Objects.equals(subAttr, PurchaseEnum.PRODUCT.getAttr())) {
                    attr = "$." + attr;
                    Long id = purchaseProductModel.isProductSubAttrExist(attr, corpid, isArray);
                    if (Objects.nonNull(id)) {
                        canDelete = false;
                    }
                }
                break;
            case RETURNED_PURCHASE:
                if (Objects.equals(subAttr, ReturnedPurchaseEnum.PRODUCTS.getAttr())) {
                    attr = "$." + attr;
                    Long id = returnedPurchaseProductModel.isProductSubAttrExist(attr, corpid, isArray);
                    if (Objects.nonNull(id)) {
                        canDelete = false;
                    }
                }
                break;
            case BOM_BILL:
                if (Objects.equals(subAttr, BomBillEnum.PRODUCT.getAttr())) {
                    attr = "$." + attr;
                    Long id = bomProductModel.isProductSubAttrExist(attr,corpid,1,isArray);
                    if (Objects.nonNull(id)) {
                        canDelete = false;
                    }
                }else if (Objects.equals(subAttr, BomBillEnum.MATERIEL.getAttr())){
                    attr = "$." + attr;
                    Long id = bomProductModel.isProductSubAttrExist(attr,corpid,2, isArray);
                    if (Objects.nonNull(id)) {
                        canDelete = false;
                    }
                }
                break;
            case PRODUCTION_ORDER:
                if (Objects.equals(subAttr, ProductionOrderEnum.PRODUCT.getAttr())) {
                    attr = "$." + attr;
                    Long id = productionOrderProductModel.isProductSubAttrExist(attr,corpid,1, isArray);
                    if (Objects.nonNull(id)) {
                        canDelete = false;
                    }
                }else if (Objects.equals(subAttr, ProductionOrderEnum.MATERIEL.getAttr())) {
                    attr = "$." + attr;
                    Long id = productionOrderProductModel.isProductSubAttrExist(attr,corpid,2, isArray);
                    if (Objects.nonNull(id)) {
                        canDelete = false;
                    }
                }
                break;
            case ASSEMBLE:
                if (Objects.equals(subAttr, AssembleEnum.IN_PRODUCTS.getAttr())) {
                    attr = "$." + attr;
                    Long id = assembleProductModel.isProductSubAttrExist(attr, corpid,2, isArray);
                    if (Objects.nonNull(id)) {
                        canDelete = false;
                    }
                }else if (Objects.equals(subAttr, AssembleEnum.OUT_PRODUCTS.getAttr())) {
                    attr = "$." + attr;
                    Long id = assembleProductModel.isProductSubAttrExist(attr, corpid,1, isArray);
                    if (Objects.nonNull(id)) {
                        canDelete = false;
                    }
                }
                break;
            case INSTOCK:
            case PURCHASE_INSTOCK:
            case REFUND_INSTOCK:
            case OTHER_INSTOCK:
            case PRODUCTION_INSTOCK:
            case RETURNED_MATERIEL_INSTOCK:
                if (Objects.equals(subAttr, InstockEnum.PRODUCT.getAttr())) {
                    attr = "$." + attr;
                    Long id = instockProductModel.isProductSubAttrExist(attr, corpid, formId, isArray);
                    if (Objects.nonNull(id)) {
                        canDelete = false;
                    }
                }
                break;
            case OUTSTOCK:
            case CONTRACT_OUTSTOCK:
            case RETURNED_PURCHASE_OUTSTOCK:
            case OTHER_OUTSTOCK:
            case PRODUCTION_MATERIEL_OUTSTOCK:
            case WORK_ORDER_OUTSTOCK:
                if (Objects.equals(subAttr, OutstockEnum.PRODUCT.getAttr())) {
                    attr = "$." + attr;
                    Long id = outstockProductModel.isProductSubAttrExist(attr, corpid, formId, isArray);
                    if (Objects.nonNull(id)) {
                        canDelete = false;
                    }
                }
                break;
            case INVENTORY:
                if (Objects.equals(subAttr, InventoryEnum.PRODUCT.getAttr())) {
                    attr = "$." + attr;
                    Long id = inventoryProductModel.isProductSubAttrExist(attr, corpid, isArray);
                    if (Objects.nonNull(id)) {
                        canDelete = false;
                    }
                }
                break;
            case TRANSFER:
                if (Objects.equals(subAttr, TransferEnum.PRODUCTS.getAttr())) {
                    attr = "$." + attr;
                    Long id = transferProductModel.isProductSubAttrExist(attr,corpid,isArray);
                    if (Objects.nonNull(id)) {
                        canDelete = false;
                    }
                }
                break;
            case WORK_ORDER:
                if (Objects.equals(subAttr, WorkOrderEnum.SPARE_PARTS.getAttr())) {
                    attr = "$." + attr;
                    Long id = workOrderProductModel.isProductSubAttrExist(attr,corpid,formId,isArray);
                    if (Objects.nonNull(id)) {
                        canDelete = false;
                    }
                }
                break;

            default:
                break;
        }
        return canDelete;
    }




    @Override
    public AttrTrashDeleteVO trashDelete(AttrTrashDeleteDTO attrTrashDeleteDTO) throws XbbException {
        String corpid = attrTrashDeleteDTO.getCorpid();
        AttrTrashEntity trashEntity = attrTrashModel.getByKey(attrTrashDeleteDTO.getId(), corpid);
        if (Objects.isNull(trashEntity)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
        }
        if (XbbRefTypeEnum.workOrderV2Form().contains(trashEntity.getBusinessType())) {
            XbbResponse<AttrTrashDeleteVO> xbbResponse = workOrderV2ExplainFeignClient.trashDelete(attrTrashDeleteDTO, LocaleContextHolder.getLocale().toString());
            if (!xbbResponse.isSuccess()) {
                throw new XbbException(xbbResponse.getCode(), xbbResponse.getMsg());
            }
            return xbbResponse.getResult();
        }
        return super.trashDelete(attrTrashDeleteDTO);
    }

    @Override
    public void trashDeleteJobs(List<AttrTrashEntity> attrTrashEntityList, UserVO loginUser) throws XbbException {
        if (CollectionUtils.isEmpty(attrTrashEntityList)) {
            return;
        }
        attrTrashEntityList.removeIf(item->XbbRefTypeEnum.workOrderV2Form().contains(item.getBusinessType()));
        super.trashDeleteJobs(attrTrashEntityList, loginUser);
    }


    @Override
    public void updateSubData(List<UpdateDataEntity> updateList, String corpid, IndexTypeEnum indexTypeEnum) throws XbbException {

        paasFormSubDataModel.updateBatch(updateList, corpid, indexTypeEnum);

    }

    @Override
    public void updateBatch(AttrTrashEntity trashEntity, String corpid, List<UpdateDataEntity> updateList) throws XbbException{
        proUpdateHelp.updateBatch(trashEntity.getSaasMark(), trashEntity.getBusinessType(), corpid, updateList, false, WriteRequest.RefreshPolicy.NONE);
    }



    /**
     * Description: 计算关联产品字段内的数量
     * @param attr
     * @param subAttr
     * @param businessType
     * @param corpid
     * @param formId
     * @param fieldType
     * @return java.lang.Long
     * @throws
     * @author 魏荣杰
     * @date 2021/3/16 14:02
     * @since
     */
    @Override
    public Long countProductNum(String attr, String subAttr, Integer businessType, String corpid, Long formId, Integer fieldType) {
        Long count = 0L;
        Integer isArray = 0;
        if (Objects.equals(FieldTypeEnum.COMBO_CHECK.getType(), fieldType)
                || Objects.equals(FieldTypeEnum.CHECKBOX_GROUP.getType(), fieldType)
                || Objects.equals(FieldTypeEnum.USER_GROUP.getType(), fieldType)
                || Objects.equals(FieldTypeEnum.DEPT_GROUP.getType(), fieldType)
                || Objects.equals(FieldTypeEnum.IMAGE.getType(), fieldType)
                || ExplainUtil.isSubForm(fieldType)) {
            isArray = 1;
        }

        XbbRefTypeEnum xbbRefTypeEnum = XbbRefTypeEnum.getByCode(businessType);
        switch (xbbRefTypeEnum){
            case CONTRACT:
                if (Objects.equals(attr, ContractEnum.PRODUCT.getAttr())) {
                    subAttr = "$." + subAttr;
                    count = contractProductModel.countProductSub(subAttr, corpid, XbbRefTypeEnum.CONTRACT.getCode(), formId, isArray);
                }
                break;
            case SALES_OPPORTUNITY:
                if (Objects.equals(attr, SalesOpportunityEnum.PRODUCTS.getAttr())) {
                    subAttr = "$." + subAttr;
                    count = opportunityProductModel.countProductSub(subAttr, corpid, formId, isArray);
                }
                break;
            case REFUND:
                if (Objects.equals(attr, RefundEnum.PRODUCTS.getAttr())) {
                    subAttr = "$." + subAttr;
                    count = contractProductModel.countProductSub(subAttr,corpid,XbbRefTypeEnum.REFUND.getCode(), formId, isArray);
                }
                break;
            case QUOTATION:
                if (Objects.equals(attr, QuotationEnum.PRODUCT.getAttr())) {
                    subAttr = "$." + subAttr;
                    count = quotationProductModel.countProductSub(subAttr, corpid, isArray);
                }
                break;
            case SUPPLIER:
                if (Objects.equals(attr, SupplierEnum.PRODUCT_LIST.getAttr())) {
                    subAttr = "$." + subAttr;
                    count = supplierProductModel.countProductSub(subAttr, corpid, isArray);
                }
                break;
            case PURCHASE:
                if (Objects.equals(attr, PurchaseEnum.PRODUCT.getAttr())) {
                    subAttr = "$." + subAttr;
                    count = purchaseProductModel.countProductSub(subAttr, corpid, isArray);
                }
                break;
            case RETURNED_PURCHASE:
                if (Objects.equals(attr, ReturnedPurchaseEnum.PRODUCTS.getAttr())) {
                    subAttr = "$." + subAttr;
                    count = returnedPurchaseProductModel.countProductSub(subAttr, corpid, isArray);
                }
                break;
            case BOM_BILL:
                if (Objects.equals(attr, BomBillEnum.PRODUCT.getAttr())) {
                    subAttr = "$." + subAttr;
                    count = bomProductModel.countProductSub(subAttr,corpid, 1,isArray);
                }else if (Objects.equals(attr, BomBillEnum.MATERIEL.getAttr())){
                    subAttr = "$." + subAttr;
                    count = bomProductModel.countProductSub(subAttr,corpid,2, isArray);
                }
                break;
            case PRODUCTION_ORDER:
                if (Objects.equals(attr, ProductionOrderEnum.PRODUCT.getAttr())) {
                    subAttr = "$." + subAttr;
                    count = productionOrderProductModel.countProductSub(subAttr, corpid, 1, isArray);
                } else if (Objects.equals(attr, ProductionOrderEnum.MATERIEL.getAttr())) {
                    subAttr = "$." + subAttr;
                    count = productionOrderProductModel.countProductSub(subAttr, corpid, 2, isArray);
                }
                break;
            case ASSEMBLE:
                if (Objects.equals(attr, AssembleEnum.IN_PRODUCTS.getAttr())) {
                    subAttr = "$." + subAttr;
                    count = assembleProductModel.countProductSub(subAttr, corpid, 2, isArray);
                }else if (Objects.equals(attr, AssembleEnum.OUT_PRODUCTS.getAttr())) {
                    subAttr = "$." + subAttr;
                    count = assembleProductModel.countProductSub(subAttr, corpid, 1, isArray);
                }
                break;
            case INSTOCK:
            case PURCHASE_INSTOCK:
            case REFUND_INSTOCK:
            case OTHER_INSTOCK:
            case PRODUCTION_INSTOCK:
            case RETURNED_MATERIEL_INSTOCK:
                if (Objects.equals(attr, InstockEnum.PRODUCT.getAttr())) {
                    subAttr = "$." + subAttr;
                    count = instockProductModel.countProductSub(subAttr, corpid, formId, isArray);
                }
                break;
            case OUTSTOCK:
            case CONTRACT_OUTSTOCK:
            case RETURNED_PURCHASE_OUTSTOCK:
            case OTHER_OUTSTOCK:
            case PRODUCTION_MATERIEL_OUTSTOCK:
            case WORK_ORDER_OUTSTOCK:
                if (Objects.equals(attr, OutstockEnum.PRODUCT.getAttr())) {
                    subAttr = "$." + subAttr;
                    count = outstockProductModel.countProductSub(subAttr, corpid, formId, isArray);
                }
                break;
            case INVENTORY:
                if (Objects.equals(attr, InventoryEnum.PRODUCT.getAttr())) {
                    subAttr = "$." + subAttr;
                    count = inventoryProductModel.countProductSub(subAttr, corpid, isArray);
                }
                break;
            case TRANSFER:
                if (Objects.equals(attr, TransferEnum.PRODUCTS.getAttr())) {
                    subAttr = "$." + subAttr;
                    count = transferProductModel.countProductSub(subAttr, corpid, isArray);
                }
                break;
            case WORK_ORDER:
                if (Objects.equals(attr, WorkOrderEnum.SPARE_PARTS.getAttr())) {
                    subAttr = "$." + subAttr;
                    count = workOrderProductModel.countProductSub(subAttr, corpid, formId, isArray);
                }
                break;
            default:
        }
        return count;
    }



    /**
     * Description:
     * @param attr
     * @param subAttr
     * @param businessType
     * @param corpid
     * @param formId
     * @param fieldType
     * @return java.lang.Long
     * @throws
     * @author 魏荣杰
     * @date 2021/3/16 15:36
     * @since
     */
    @Override
    public void deleteProductSubData(String attr, String subAttr, Integer businessType, String corpid, Long formId, Integer fieldType) throws XbbException {
        Integer isArray = 0;
        if (Objects.equals(FieldTypeEnum.COMBO_CHECK.getType(), fieldType)
                || Objects.equals(FieldTypeEnum.CHECKBOX_GROUP.getType(), fieldType)
                || Objects.equals(FieldTypeEnum.USER_GROUP.getType(), fieldType)
                || Objects.equals(FieldTypeEnum.DEPT_GROUP.getType(), fieldType)
                || Objects.equals(FieldTypeEnum.IMAGE.getType(), fieldType)
                || ExplainUtil.isSubForm(fieldType)) {
            isArray = 1;
        }

        XbbRefTypeEnum xbbRefTypeEnum = XbbRefTypeEnum.getByCode(businessType);
        String attrStr;
        boolean flag = true;
        Integer limit = 500;
        Long idGte = 0L;
        switch (xbbRefTypeEnum){
            case CONTRACT:
                if (Objects.equals(attr, ContractEnum.PRODUCT.getAttr())) {
                    attrStr = "$." + subAttr;
                    while (flag) {
                        List<ContractProductEntity> contractProductEntities = contractProductModel.getProductWithSubData(attrStr, corpid, XbbRefTypeEnum.CONTRACT.getCode(), formId, isArray, idGte, limit);
                        if (contractProductEntities.isEmpty()) {
                            flag = false;
                        } else {
                            idGte = contractProductEntities.get(contractProductEntities.size() - 1).getId();
                            Iterator<ContractProductEntity> iterator = contractProductEntities.iterator();
                            while (iterator.hasNext()) {
                                ContractProductEntity contractProductEntity = iterator.next();
                                JSONObject data = contractProductEntity.getData();
                                data.entrySet().removeIf(item -> Objects.equals(subAttr, item.getKey()));
                                contractProductModel.update(contractProductEntity);
                            }
                        }

                    }


                }
                break;
            case SALES_OPPORTUNITY:
                if (Objects.equals(attr, SalesOpportunityEnum.PRODUCTS.getAttr())) {
                    attrStr = "$." + subAttr;
                    while (flag) {
                        List<OpportunityProductEntity> opportunityProductEntities = opportunityProductModel.getProductWithSubData(attrStr, corpid, formId, isArray, idGte, limit);
                        if (opportunityProductEntities.isEmpty()) {
                            flag = false;
                        } else {
                            idGte = opportunityProductEntities.get(opportunityProductEntities.size() - 1).getId();
                            Iterator<OpportunityProductEntity> iterator = opportunityProductEntities.iterator();
                            while (iterator.hasNext()) {
                                OpportunityProductEntity opportunityProductEntity = iterator.next();
                                JSONObject data = opportunityProductEntity.getData();
                                data.entrySet().removeIf(item -> Objects.equals(subAttr, item.getKey()));
                                opportunityProductModel.update(opportunityProductEntity);
                            }

                        }
                    }
                }
                break;
            case REFUND:
                if (Objects.equals(attr, RefundEnum.PRODUCTS.getAttr())) {
                    attrStr = "$." + subAttr;
                    while (flag) {
                        List<ContractProductEntity> refundProducts = contractProductModel.getProductWithSubData(attrStr, corpid, XbbRefTypeEnum.REFUND.getCode(), formId, isArray, idGte, limit);
                        if (refundProducts.isEmpty()) {
                            flag = false;
                        } else {
                            idGte = refundProducts.get(refundProducts.size() - 1).getId();
                            Iterator<ContractProductEntity> iterator = refundProducts.iterator();
                            while (iterator.hasNext()) {
                                ContractProductEntity refundProduct = iterator.next();
                                JSONObject data = refundProduct.getData();
                                data.entrySet().removeIf(item -> Objects.equals(item.getKey(), subAttr));
                                contractProductModel.update(refundProduct);
                            }

                        }
                    }

                }
                break;
            case QUOTATION:
                if (Objects.equals(attr, QuotationEnum.PRODUCT.getAttr())) {
                    attrStr = "$." + subAttr;
                    while (flag) {
                        List<QuotationProductEntity> quotationProductEntities = quotationProductModel.getProductWithSubData(attrStr, corpid, isArray, idGte, limit);
                        if (quotationProductEntities.isEmpty()) {
                            flag = false;
                        } else {
                            idGte = quotationProductEntities.get(quotationProductEntities.size() - 1).getId();
                            Iterator<QuotationProductEntity> iterator = quotationProductEntities.iterator();
                            while (iterator.hasNext()) {
                                QuotationProductEntity quotationProductEntity = iterator.next();
                                JSONObject data = quotationProductEntity.getData();
                                data.entrySet().removeIf(item -> Objects.equals(item.getKey(), subAttr));
                                quotationProductModel.update(quotationProductEntity);
                            }

                        }
                    }
                }
                break;
            case SUPPLIER:
                if (Objects.equals(attr, SupplierEnum.PRODUCT_LIST.getAttr())) {
                    attrStr = "$." + subAttr;
                    while (flag) {
                        List<SupplierProductEntity> supplierProductEntities = supplierProductModel.getProductWithSubData(attrStr, corpid, isArray, idGte, limit);
                        if (supplierProductEntities.isEmpty()) {
                            flag = false;
                        } else {
                            idGte = supplierProductEntities.get(supplierProductEntities.size() - 1).getId();
                            Iterator<SupplierProductEntity> iterator = supplierProductEntities.iterator();
                            while (iterator.hasNext()) {
                                SupplierProductEntity supplierProductEntity = iterator.next();
                                JSONObject data = supplierProductEntity.getData();
                                data.entrySet().removeIf(item -> Objects.equals(item.getKey(), subAttr));
                                supplierProductModel.update(supplierProductEntity);
                            }

                        }
                    }
                }
                break;
            case PURCHASE:
                if (Objects.equals(attr, PurchaseEnum.PRODUCT.getAttr())) {
                    attrStr = "$." + subAttr;
                    while (flag) {
                        List<PurchaseProductEntity> purchaseProductEntities = purchaseProductModel.getProductWithSubData(attrStr, corpid, isArray, idGte, limit);
                        if (purchaseProductEntities.isEmpty()) {
                            flag = false;
                        } else {
                            idGte = purchaseProductEntities.get(purchaseProductEntities.size() - 1).getId();
                            Iterator<PurchaseProductEntity> iterator = purchaseProductEntities.iterator();
                            while (iterator.hasNext()) {
                                PurchaseProductEntity purchaseProductEntity = iterator.next();
                                JSONObject data = purchaseProductEntity.getData();
                                data.entrySet().removeIf(item -> Objects.equals(item.getKey(), subAttr));
                                purchaseProductModel.update(purchaseProductEntity);
                            }

                        }
                    }
                }
                break;
            case RETURNED_PURCHASE:
                if (Objects.equals(attr, ReturnedPurchaseEnum.PRODUCTS.getAttr())) {
                    attrStr = "$." + subAttr;
                    while (flag) {
                        List<ReturnedPurchaseProductEntity> returnedPurchaseProductEntities = returnedPurchaseProductModel.getProductWithSubData(attrStr, corpid, isArray, idGte, limit);
                        if (returnedPurchaseProductEntities.isEmpty()) {
                            flag = false;
                        } else {
                            idGte = returnedPurchaseProductEntities.get(returnedPurchaseProductEntities.size() - 1).getId();
                            Iterator<ReturnedPurchaseProductEntity> iterator = returnedPurchaseProductEntities.iterator();
                            while (iterator.hasNext()) {
                                ReturnedPurchaseProductEntity returnedPurchaseProductEntity = iterator.next();
                                JSONObject data = returnedPurchaseProductEntity.getData();
                                data.entrySet().removeIf(item -> Objects.equals(item.getKey(), subAttr));
                                returnedPurchaseProductModel.update(returnedPurchaseProductEntity);
                            }

                        }
                    }

                }
                break;
            case BOM_BILL:
                if (Objects.equals(attr, BomBillEnum.PRODUCT.getAttr())) {
                    attrStr = "$." + subAttr;
                    while (flag) {
                        List<BomProductEntity> bomProductEntities = bomProductModel.getProductWithSubData(attrStr, corpid, 1, isArray, idGte, limit);
                        if (bomProductEntities.isEmpty()) {
                            flag = false;
                        } else {
                            idGte = bomProductEntities.get(bomProductEntities.size() - 1).getId();
                            Iterator<BomProductEntity> iterator = bomProductEntities.iterator();
                            while (iterator.hasNext()) {
                                BomProductEntity bomProductEntity = iterator.next();
                                JSONObject data = bomProductEntity.getData();
                                data.entrySet().removeIf(item -> Objects.equals(item.getKey(), subAttr));
                                bomProductModel.update(bomProductEntity);
                            }

                        }
                    }
                }else if (Objects.equals(attr, BomBillEnum.MATERIEL.getAttr())){
                    attrStr = "$." + subAttr;
                    while (flag) {
                        List<BomProductEntity> bomProductEntities = bomProductModel.getProductWithSubData(attrStr, corpid, 2, isArray, idGte, limit);
                        if (bomProductEntities.isEmpty()) {
                            flag = false;
                        } else {
                            idGte = bomProductEntities.get(bomProductEntities.size() - 1).getId();
                            Iterator<BomProductEntity> iterator = bomProductEntities.iterator();
                            while (iterator.hasNext()) {
                                BomProductEntity bomProductEntity = iterator.next();
                                JSONObject data = bomProductEntity.getData();
                                data.entrySet().removeIf(item -> Objects.equals(item.getKey(), subAttr));
                                bomProductModel.update(bomProductEntity);
                            }

                        }
                    }
                }
                break;
            case PRODUCTION_ORDER:
                if (Objects.equals(attr, ProductionOrderEnum.PRODUCT.getAttr())) {
                    attrStr = "$." + subAttr;
                    while (flag) {
                        List<ProductionOrderProductEntity> productionOrderProductEntities = productionOrderProductModel.getProductWithSubData(attrStr, corpid, 1, isArray, idGte, limit);
                        if (productionOrderProductEntities.isEmpty()) {
                            flag = false;
                        } else {
                            idGte = productionOrderProductEntities.get(productionOrderProductEntities.size() - 1).getId();

                            Iterator<ProductionOrderProductEntity> iterator = productionOrderProductEntities.iterator();
                            while (iterator.hasNext()) {
                                ProductionOrderProductEntity productionOrderProductEntity = iterator.next();
                                JSONObject data = productionOrderProductEntity.getData();
                                data.entrySet().removeIf(item -> Objects.equals(item.getKey(), subAttr));
                                productionOrderProductModel.update(productionOrderProductEntity);
                            }

                        }
                    }
                } else if (Objects.equals(attr, ProductionOrderEnum.MATERIEL.getAttr())) {
                    attrStr = "$." + subAttr;
                    while (flag) {
                        List<ProductionOrderProductEntity> productionOrderProductEntities = productionOrderProductModel.getProductWithSubData(attrStr, corpid, 2, isArray, idGte, limit);
                        if (productionOrderProductEntities.isEmpty()) {
                            flag = false;
                        } else {
                            idGte = productionOrderProductEntities.get(productionOrderProductEntities.size() - 1).getId();

                            Iterator<ProductionOrderProductEntity> iterator = productionOrderProductEntities.iterator();
                            while (iterator.hasNext()) {
                                ProductionOrderProductEntity productionOrderProductEntity = iterator.next();
                                JSONObject data = productionOrderProductEntity.getData();
                                data.entrySet().removeIf(item -> Objects.equals(item.getKey(), subAttr));
                                productionOrderProductModel.update(productionOrderProductEntity);
                            }

                        }
                    }
                }
                break;
            case ASSEMBLE:
                if (Objects.equals(attr, AssembleEnum.IN_PRODUCTS.getAttr())) {
                    attrStr = "$." + subAttr;
                    while (flag) {
                        List<AssembleProductEntity> assembleProductEntities = assembleProductModel.getProductWithSubData(attrStr, corpid, 2, isArray, idGte, limit);
                        if (assembleProductEntities.isEmpty()) {
                            flag = false;
                        } else {
                            idGte = assembleProductEntities.get(assembleProductEntities.size() - 1).getId();
                            Iterator<AssembleProductEntity> iterator = assembleProductEntities.iterator();
                            while (iterator.hasNext()) {
                                AssembleProductEntity assembleProductEntity = iterator.next();
                                JSONObject data = assembleProductEntity.getData();
                                data.entrySet().removeIf(item -> Objects.equals(item.getKey(), subAttr));
                                assembleProductModel.update(assembleProductEntity);
                            }

                        }
                    }
                }else if (Objects.equals(attr, AssembleEnum.OUT_PRODUCTS.getAttr())) {
                    attrStr = "$." + subAttr;
                    while (flag) {
                        List<AssembleProductEntity> assembleProductEntities = assembleProductModel.getProductWithSubData(attrStr, corpid, 1, isArray, idGte, limit);
                        if (assembleProductEntities.isEmpty()) {
                            flag = false;
                        } else {
                            idGte = assembleProductEntities.get(assembleProductEntities.size() - 1).getId();
                            Iterator<AssembleProductEntity> iterator = assembleProductEntities.iterator();
                            while (iterator.hasNext()) {
                                AssembleProductEntity assembleProductEntity = iterator.next();
                                JSONObject data = assembleProductEntity.getData();
                                data.entrySet().removeIf(item -> Objects.equals(item.getKey(), subAttr));
                                assembleProductModel.update(assembleProductEntity);
                            }

                        }
                    }
                }
                break;
            case INSTOCK:
            case PURCHASE_INSTOCK:
            case REFUND_INSTOCK:
            case OTHER_INSTOCK:
            case PRODUCTION_INSTOCK:
            case RETURNED_MATERIEL_INSTOCK:
                if (Objects.equals(attr, InstockEnum.PRODUCT.getAttr())) {
                    attrStr = "$." + subAttr;
                    while (flag) {
                        List<InstockProductEntity> instockProductEntities = instockProductModel.getProductWithSubData(attrStr, corpid, formId, isArray, idGte, limit);
                        if (instockProductEntities.isEmpty()) {
                            flag = false;
                        } else {
                            idGte = instockProductEntities.get(instockProductEntities.size() - 1).getId();
                            Iterator<InstockProductEntity> iterator = instockProductEntities.iterator();
                            while (iterator.hasNext()) {
                                InstockProductEntity instockProductEntity = iterator.next();
                                instockProductEntity.getData().entrySet().removeIf(item -> Objects.equals(item.getKey(), subAttr));
                                instockProductModel.update(instockProductEntity);
                            }

                        }
                    }

                }
                break;
            case OUTSTOCK:
            case CONTRACT_OUTSTOCK:
            case RETURNED_PURCHASE_OUTSTOCK:
            case OTHER_OUTSTOCK:
            case PRODUCTION_MATERIEL_OUTSTOCK:
            case WORK_ORDER_OUTSTOCK:
                if (Objects.equals(attr, OutstockEnum.PRODUCT.getAttr())) {
                    attrStr = "$." + subAttr;
                    while (flag) {
                        List<OutstockProductEntity> outstockProductEntities = outstockProductModel.getProductWithSubData(attrStr, corpid, formId, isArray, idGte, limit);
                        if (outstockProductEntities.isEmpty()) {
                            flag = false;
                        } else {
                            idGte = outstockProductEntities.get(outstockProductEntities.size() - 1).getId();
                            Iterator<OutstockProductEntity> iterator = outstockProductEntities.iterator();
                            while (iterator.hasNext()) {
                                OutstockProductEntity outstockProductEntity = iterator.next();
                                outstockProductEntity.getData().entrySet().removeIf(item -> Objects.equals(item.getKey(), subAttr));
                                outstockProductModel.update(outstockProductEntity);
                            }

                        }
                    }

                }
                break;
            case INVENTORY:
                if (Objects.equals(attr, InventoryEnum.PRODUCT.getAttr())) {
                    attrStr = "$." + subAttr;
                    while (flag) {
                        List<InventoryProductEntity> inventoryProductEntities = inventoryProductModel.getProductWithSubData(attrStr, corpid, isArray, idGte, limit);
                        if (inventoryProductEntities.isEmpty()) {
                            flag = false;
                        } else {
                            idGte = inventoryProductEntities.get(inventoryProductEntities.size() - 1).getId();
                            Iterator<InventoryProductEntity> iterator = inventoryProductEntities.iterator();
                            while (iterator.hasNext()) {
                                InventoryProductEntity inventoryProductEntity = iterator.next();
                                inventoryProductEntity.getData().entrySet().removeIf(item -> Objects.equals(item.getKey(), subAttr));
                                inventoryProductModel.update(inventoryProductEntity);
                            }

                        }
                    }
                }
                break;
            case TRANSFER:
                if (Objects.equals(attr, TransferEnum.PRODUCTS.getAttr())) {
                    attrStr = "$." + subAttr;
                    while (flag) {
                        List<TransferProductEntity> transferProductEntities = transferProductModel.getProductWithSubData(attrStr, corpid, isArray, idGte, limit);
                        if (transferProductEntities.isEmpty()) {
                            flag = false;
                        } else {
                            idGte = transferProductEntities.get(transferProductEntities.size() - 1).getId();
                            Iterator<TransferProductEntity> iterator = transferProductEntities.iterator();
                            while (iterator.hasNext()) {
                                TransferProductEntity transferProductEntity = iterator.next();
                                transferProductEntity.getData().entrySet().removeIf(item -> Objects.equals(item.getKey(), subAttr));
                                transferProductModel.update(transferProductEntity);
                            }

                        }
                    }
                }
                break;
            case WORK_ORDER:
                if (Objects.equals(attr, WorkOrderEnum.SPARE_PARTS.getAttr())) {
                    attrStr = "$." + subAttr;
                    while (flag) {
                        List<WorkOrderProductEntity> workOrderProductEntities = workOrderProductModel.getProductWithSubData(attrStr, corpid, formId, isArray, idGte, limit);
                        if (workOrderProductEntities.isEmpty()) {
                            flag = false;
                        } else {
                            idGte = workOrderProductEntities.get(workOrderProductEntities.size() - 1).getId();
                            Iterator<WorkOrderProductEntity> iterator = workOrderProductEntities.iterator();
                            while (iterator.hasNext()) {
                                WorkOrderProductEntity workOrderProductEntity = iterator.next();
                                workOrderProductEntity.getData().entrySet().removeIf(item -> Objects.equals(item.getKey(), subAttr));
                                workOrderProductModel.update(workOrderProductEntity);
                            }

                        }
                    }
                }
                break;
            default:
        }
    }



}
